<?php
require_once("conf.php");
require_once("captcha_parameters.php");
require_once("utils.php");
require_once("HTML/Menu.php");
require_once("HTML/Menu/DirectTreeRenderer.php");
require_once("HTTP.php");
relro(__FILE__,"../data/User.php");

//Start the session
session_start();

//The HTTP parameter which contains the base 64 encoded URL to which the login page must
//redirect the user once the authentication is a success
define("BACK_URL","_ru");
define("ERROR_CODE","_ec");
define("PROFILE_UPDATE_KEY","_key");
define("ZOOMAREA_ID_PARAMETER","_zoomId");
define("ZOOMAREA_CLOSEFUNC_PARAMETER","_zoomClose");

//-------------------------------------------------------------------------
//******************** Menu MANAGEMENT *********************************
//-------------------------------------------------------------------------

//The navigation menu structure
global $MENU_DATA;

$MENU_DATA=array(
	1 => array(
		'title' => 'Home',
		'url' => ROOT_PATH . '/apps/index.php'
		), 
	2 => array(
		'title' => 'My profile',
		'url' => ROOT_PATH . '/apps/user/profile/index.php',
		'sub' => array(
			21 => array(
				'title' => 'Update my profile',
				'url' => ROOT_PATH . '/apps/user/profile/profile_update.php'
			),
			22 => array(
				'title' => 'Change password',
				'url' => ROOT_PATH . '/apps/user/profile/password_change.php'
			)
		)
	),
	3 => array(
		'title' => 'My dashboard',
		'url' => ROOT_PATH . '/apps/user/dashboard/index.php',
		'sub' => array(
			31 => array(
				'title' => 'Team overview',
				'url' => ROOT_PATH . '/apps/user/dashboard/team_overview.php'
			),
			32 => array(
				'title' => 'Per activity',
				'url' => ROOT_PATH . '/apps/user/dashboard/per_activity_dashboard.php'
			),
			33 => array(
				'title' => 'Post an action',
				'url' => ROOT_PATH . '/apps/user/dashboard/add_action.php'
			)
		)
	),
	4 => array(
		'title' => 'My reporting',
		'url' => ROOT_PATH . '/apps/user/report/index.php',
		'sub' => array(
			41 => array(
				'title' => 'Weekly report',
				'url' => ROOT_PATH . '/apps/user/report/weekly_report.php'
			),
			42 => array(
				'title' => 'History',
				'url' => ROOT_PATH . '/apps/user/report/manage_reports.php'
			)
		)
	),
	5 => array(
		'title' => 'Search',
		'url' => ROOT_PATH . '/apps/user/search/index.php'
	),
	6 => array(
			'title' => 'Admin',
			'url' => ROOT_PATH . '/apps/admin/index.php',
			'sub' => array(
				61 => array(
					'title' => 'Invite new user',
					'url' => ROOT_PATH . '/apps/admin/invite.php'
				),
				62 => array(
					'title' => 'Users management',
					'url' => ROOT_PATH . '/apps/admin/manage_users.php'
				),
				63 => array(
					'title' => 'Add an activity',
					'url' => ROOT_PATH . '/apps/admin/update_activity.php'
				),
				64 => array(
					'title' => 'Activites management',
					'url' => ROOT_PATH . '/apps/admin/manage_activities.php'
				),
				65 => array(
					'title' => 'Activities Import/Export',
					'url' => ROOT_PATH . '/apps/admin/import_export_activities.php'
				)
	))
);

//Perform adaptations to the menu if the session is active
if(SessionManager::isSessionActive()){
	$l_user=User::getFromPrimaryKey(SessionManager::getCurrentLoggedUserId());
	$l_managerId=$l_user->getManagerUser_Id();
	if(!isset($l_managerId)){
		unset($MENU_DATA[4]);
	}
	if(!$l_user->getIsAdmin()){
		unset($MENU_DATA[6]);
	}
}

//-------------------------------------------------------------------------
//******************** SESSION MANAGEMENT *********************************
//-------------------------------------------------------------------------

/**
 * This class deal with the management of the session and
 * the login process
 */
class SessionManager{
	private static $instance;
	
	//Session related constants
	const SESSION_USER_ID="user.id";
	const SESSION_USER_EMAIL="user.email";
	const SESSION_USER_DISPLAYNAME="user.displayName";
	const SESSION_USER_ISADMIN="user.isadmin";
	const SESSION_USER_ISFINANCEADMIN="user.isfinanceadmin";
	const SESSION_USER_ISMANAGER="user.ismanager";
	
	private function __construct(){
	}
	
	/**
	 * Return the single instance of the SessionManager
	 */
	public static function getInstance(){
		if(!isset(self::$instance)){
			self::$instance=new SessionManager();
		}
		return self::$instance;
	}
	
	/**
	 * Check if a valid session is opened
	 * @return boolean true if a session is opened
	 */
	public function isSessionActive(){
		return (isset($_SESSION[self::SESSION_USER_ID]));
	}
	
	/**
	 * Check if a valid session is opened otherwise initiate a login
	 * @return boolean true if a session is opened
	 */
	public function checkSession(){
		if(!isset($_SESSION[self::SESSION_USER_ID])){
			$this->initiateLogin();
		}else{
			return true;
		}
	}
	
	/**
	 * Create a new session from the User object passed
	 * as a paremeter
	 * @param p_user a User instance
	 */
	public function createSession($p_user){
		$_SESSION[self::SESSION_USER_ID]=$p_user->getId();
		$_SESSION[self::SESSION_USER_EMAIL]=$p_user->getEmail();
		$_SESSION[self::SESSION_USER_DISPLAYNAME]=$p_user->getFirstName() . " " . $p_user->getLastName();
		$_SESSION[self::SESSION_USER_ISADMIN]=$p_user->getIsAdmin();
		$_SESSION[self::SESSION_USER_ISFINANCEADMIN]=$p_user->getIsFinanceAdmin();
		session_commit();
	}
	
	/**
	 * Delete the currently active session (logout)
	 */
	public function deleteSession(){
		session_destroy();
	}
	
	/**
	 * Return the display name of the currently logged user
	 * @return  string a display name
	 */
	public function getCurrentLoggedUserDisplayName(){
		return $_SESSION[self::SESSION_USER_DISPLAYNAME];
	}
	
	/**
	 * Return the id of the currently logged user
	 * @return  string a user id
	 */
	public function getCurrentLoggedUserId(){
		return $_SESSION[self::SESSION_USER_ID];
	}
	
	/**
	 * Return true if the user is super admin
	 * @return boolean 
	 */
	public function isSuperAdmin(){
		return $_SESSION[self::SESSION_USER_ISADMIN];
	}
	
	/**
	 * Return true if the user is finance admin
	 * @return boolean 
	 */
	public function isFinanceAdmin(){
		return $_SESSION[self::SESSION_USER_ISFINANCEADMIN];
	}
	
	/**
	 * Initiate the login session
	 */
	private function initiateLogin(){
		$l_backUrl=base64_encode(getSelfURL());
		HTTP::redirect(ROOT_PATH . "/apps/login/login.php?" . BACK_URL . "={$l_backUrl}");
	}
}

//----------------------------------------------------------------
//********************** MENU MANAGEMENT *************************
//----------------------------------------------------------------
	
	/**
	 * Display the menu
	 */
	function displayMenu(){
		 global $MENU_DATA;
		 if(SessionManager::isSessionActive()){
			 $l_menu =& new HTML_Menu($MENU_DATA);
			 $l_renderer=new HTML_Menu_DirectTreeRenderer();
			 $l_menu->render($l_renderer,'tree');
			 echo $l_renderer->toHtml();
		 }
	}
	
//----------------------------------------------------------------
//********************* ERROR MANAGEMENT *************************
//----------------------------------------------------------------
	
	/**
	 * Redirect to an error page with the specified message
	 */
	function displayError($p_errorMessage){
		HTTP::redirect(ROOT_PATH . "/apps/resources/error.php?". ERROR_CODE . "=" . base64_encode($p_errorMessage));
	}

//----------------------------------------------------------------
//********************** TEMPLATE TOP ****************************
//----------------------------------------------------------------

	/**
	 * Display the top part of the page
	 *
	 * @param string $p_title the title of the page
	 * @param string $p_scripts the JavaScripts to embbed in this page
	 * @param string $p_message a status message to be displayed
	 */
	function displayTop($p_title,$p_scripts,$p_message){
		$currentLoggedUserDisplayName=SessionManager::getInstance()->getCurrentLoggedUserDisplayName();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type" /><title><?=$p_title ?></title>
<link rel="stylesheet" href="<?=ROOT_PATH ?>/apps/resources/stylesheet.css" type="text/css" />
<?php
//----------------------------------------------------------------
// Additional JavaScripts and CSS for this page
//----------------------------------------------------------------
if(isset($p_scripts)){
	include_once($p_scripts);
}
//----------------------------------------------------------------
?>
</head>
<body>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td align="center" valign="middle" style="width: 50px;">
<img style="width: 46px; height: 46px;" alt="Orange" src="<?=ROOT_PATH ?>/apps/resources/logo.png" />
</td>
<td valign="middle" style="width: 100px;">
IATB<br/>
Management<br/>
System
</td>
<td>
	<table width="100%">
	<tr><td></td></tr>
	<tr>
	<td style="text-align: left;background-color: rgb(255, 204, 153);padding: 2px;">
	<font size="+1"><?=$p_title ?></font>
	</td>
	</tr>
	<tr><td></td></tr>
	</table>
</td>
</tr>
</tbody>
</table>
<hr style="height: 1px; width: 100%;" noshade="noshade" />
<?php
if(isset($p_message)){
	?>
<table width="100%" border="0" bgcolor="#000000"><tr><td align="center"><font style="color: white;font-weight: bold"><?=$p_message; ?></font></td></tr></table>
<hr style="height: 1px; width: 100%;" noshade="noshade" />
	<?php
}
?>
<?php
if(isset($currentLoggedUserDisplayName)){ 
?>
<div style="text-align: right;"><?=$currentLoggedUserDisplayName ?> is logged - <a href="<?=ROOT_PATH ?>/apps/login/logout.php">logout</a></div>
<?php
}
?>
<br/>
<table width="100%">
<tr>
<td valign="top" width="150px">
<?php
//----------------------------------------------------------------
// Additional JavaScripts and CSS for this page
//----------------------------------------------------------------
displayMenu();
//----------------------------------------------------------------
?>
</td>
<td width="30px"></td>
<td>	
<?php
	}
	
	
//----------------------------------------------------------------
//********************** SIMPLE TEMPLATE TOP *********************
//----------------------------------------------------------------
	
	/**
	 * Display a simplified version of the top part of a page.<br/>
	 * This is useful for pages which needs to be printed.
	 *
	 * @param string $p_title the title of the page
	 */
	function displaySimpleTop($p_title){
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type" /><title><?=$p_title ?></title>
<link rel="stylesheet" href="<?=ROOT_PATH ?>/apps/resources/stylesheet.css" type="text/css" />
</head>
<body>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td>
<?
	}
	
//---------------------------------------------------------------
//*********************** TEMPLATE BOTTOM ***********************
//---------------------------------------------------------------
	
	/**
	 * Display the bottom part of the page
	 */
	function displayBottom(){
?>
</td>
</tr>
</tbody>
</table>
<hr style="height: 1px; width: 100%;" noshade="noshade" />
<div style="text-align: right;"><span style="font-weight: normal;"><?=FOOTER_DISCLAIMER ?></span><br />
</div>
</body></html>
<?php
	}
	
//---------------------------------------------------------------
//*********************** SIMPLE TEMPLATE BOTTOM ****************
//---------------------------------------------------------------
	
	/**
	 * Display the bottom part of the page.<br/>
	 * Simplified version without the copyright.
	 */
	function displaySimpleBottom(){
?>
</td>
</tr>
</tbody>
</table>
</body></html>
<?php
	}

	
//-------------------------------------------------------------------
//************************** TABLE DISPLAY **************************
//-------------------------------------------------------------------

/**
 * The structure which contains the data to be used to generate the HTML table
 */
class TableData{
	private $name;
	private $records;
	private $fieldNames;
	private $headersLabel;
	private $actions;
	private $zoomAreaScript;
	
	public function __construct($p_name){
		$this->name=$p_name;
		$fieldNames=array();
		$headersLabel=array();
		$actions=array();
	}
	
	/**
	 * Set the values to be inserted into the table.
	 * These values are provided as an array of objects indexed by the primary key value.
	 * @param array $p_records
	 */
	public function setRecords($p_records){
		$this->records=$p_records;
	}
	
	/**
	 * Get the values to be inserted into the table.
	 * These values are provided as an array of objects indexed by the primary key value.
	 * @return array of objects
	 */
	public function getRecords(){
		return $this->records;
	}
	
	/**
	 * Add a header to the table
	 * @param string $p_fieldName The name of the field (name of the member in the records objects)
	 * @param string $p_fieldLabel The header label to be displayed
	 */
	public function addHeader($p_fieldName, $p_fieldLabel){
		$this->fieldNames[]=$p_fieldName;
		$this->headersLabel[]=$p_fieldLabel;
	}
	
	/**
	 * Add an action to be added to the table.
	 * An action is a call back function which must be implemented in the page which displays
	 * the table.
	 * @param string the name of a function to "call back"
	 */
	public function addAction($p_callBackFunction){
		$this->actions[]=$p_callBackFunction;
	}
	
	/**
	 * Add a dropdown zone to each record.
	 * The content of this dropdown zone is to be filled by the HTML
	 * returned by the specified PHP script (asynchronously using an AJAX call).
	 * WARNING: the appropriate scriptaculous scripts must be added to the page
	 * @param string $p_zoomAreaScript the URL to a PHP script
	 */
	public function setZoomArea($p_zoomAreaScript){
		$this->zoomAreaScript=$p_zoomAreaScript;
	}
	
	/**
	 * Return the AJAX script to get the content of the zoom area.<br>
	 * Two $_REQUEST variables will be available within this script:
	 * <ul>
	 * <li>ZOOMAREA_ID_PARAMETER: the base64 encoded id of the record to be displayed</li>
	 * <li>ZOOMAREA_CLOSEFUNC_PARAMETER: the name of the JavaScript function to be called to close the dropdown</li>
	 * </ul>
	 * @return string
	 */
	public function getZoomArea(){
		return $this->zoomAreaScript;
	}
	
	/**
	 * Return true if the records of the table are to be associated with a Zoomarea
	 * @return boolean
	 */
	public function hasZoomArea(){
		return isset($this->zoomAreaScript);
	}
	
	/**
	 * Return the name of the table
	 */
	public function getName(){
		return $this->name;
	}
	
	/**
	 * Return the value associated with the specified field name.
	 * Actually the field name must match the name of a record object method "getFieldname"
	 * @param string $p_record a record object
	 * @param string $p_fieldName the name of a record object attribute
	 * @return mixed
	 */
	public function getFieldValue($p_record, $p_fieldName){
		$l_method = new ReflectionMethod(get_class($p_record), "get" . ucfirst($p_fieldName));
		return $l_method->invoke($p_record);
	}
	
	/**
	 * Return an array of string (the header labels)
	 * @return array
	 */
	public function getHeaderLabels(){
		return $this->headersLabel;
	}
	
	/**
	 * Return an array of string (the field names = record object attribute)
	 * @return array
	 */
	public function getFieldNames(){
		return $this->fieldNames;
	}
	
	/**
	 * Return true if the table is associated with some actions
	 * @return boolean
	 */
	public function hasActions(){
		return count($this->actions)!=0;
	}
	
	/**
	 * Return the actions links by calling the actions "callbacks"
	 * @param mixed $p_record an object
	 */
	public function getActionsLinks($p_record){
		$l_htmlDisplay="";
		foreach($this->actions as $l_action){
			$l_htmlDisplay=$l_htmlDisplay . call_user_func($l_action,$p_record);
		}
		return $l_htmlDisplay;
	}
}

/**
 * Return an HTML table
 * @param TableData an instance of TableData
 */
function displayTable($p_tableData){
	if($p_tableData->hasZoomArea()){
	?>
	<script language="javascript">
		function loadAndDisplayFor<?=$p_tableData->getName() ?>(recordId){
			Effect.SlideDown("<?=$p_tableData->getName() ?>_frame_"+recordId,{duration: 0.5});
			ahah("<?=$p_tableData->getZoomArea() ?>?<?=ZOOMAREA_ID_PARAMETER ?>="+recordId+"&<?=ZOOMAREA_CLOSEFUNC_PARAMETER ?>=undisplayFor<?=$p_tableData->getName() ?>","<?=$p_tableData->getName() ?>_value_"+recordId,"<?=ROOT_PATH . "/apps/resources/images" ?>");
			return false;
		}
		
		function undisplayFor<?=$p_tableData->getName() ?>(recordId){
			Effect.SlideUp("<?=$p_tableData->getName() ?>_frame_"+recordId,{duration: 0.5});
			document.getElementById("<?=$p_tableData->getName() ?>_value_"+recordId).innerHTML ="";
			return false;
		}
	</script>
	<?php
	}
	?>
	<table class="decoratedTable" width="100%">
	<tr class="decoratedTableHeader">
		<?php
		if($p_tableData->hasZoomArea()){
		?>
		<td></td>
		<?php
		}
		$l_headers=$p_tableData->getHeaderLabels();
		foreach($l_headers as $l_header){
			//Display the headers
			?>
		<td>
			<?=$l_header ?>
		</td>
			<?php
		}
		if($p_tableData->hasActions()){
		?>
		<td></td>
		<?php
		}
		?>
	</tr>
	<?php
	$l_alternate=true;
	foreach($p_tableData->getRecords() as $l_record){
		//Display the records	
		if($l_alternate){
			$l_rowStyle="decoratedTableRow";
		}else{
			$l_rowStyle="decoratedTableRowGrey";
		}
		$l_alternate=!$l_alternate;
		?>
		<tr class="<?=$l_rowStyle ?>">
			<?php
			if($p_tableData->hasZoomArea()){
			?>
			<td>
			<a href="#" onclick="return loadAndDisplayFor<?=$p_tableData->getName() ?>('<?=base64_encode($l_record->getId()) ?>');"><img border="0" src="<?=ROOT_PATH ?>/apps/resources/images/expands.png"/></a>
			</td>
			<?php
			}
			?>
			<?php
			$l_fieldNames=$p_tableData->getFieldNames();
			foreach($l_fieldNames as $l_fieldName){
			?> 
			<td>
				<?=$p_tableData->getFieldValue($l_record,$l_fieldName) ?>
			</td>
			<?php
			}
			if($p_tableData->hasActions()){
			?>
			<td>
				<?php
				$p_tableData->getActionsLinks($l_record);
				?>
			</td>
			<?php
			}
			?>
		</tr>
		<?php
		if($p_tableData->hasZoomArea()){
			$l_colSpan=count($p_tableData->getHeaderLabels())+1;
			if($p_tableData->hasActions()){
				$l_colSpan=$l_colSpan+1;
			}
			?>
		<tr>
		<td width="10"></td>
		<td colspan="<?=($l_colSpan-1) ?>">
		<div id="<?=$p_tableData->getName() ?>_frame_<?=base64_encode($l_record->getId()) ?>" style="display:none;">
		<div id="<?=$p_tableData->getName() ?>_value_<?=base64_encode($l_record->getId()) ?>" class="decoratedDropDownTableRow"></div>
		</div>
		</td>
		</tr>
			<?php
		}	
	}
	?>
	</table>
	<?php
}	
?>